package com.kfm.advice;

import com.kfm.anno.M;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

/**
 * 通知类
 *   要对方法的增强内容写在这里
 */
@Aspect
@Component
public class AdviceConfig {


    private static final Logger LOG = Logger.getLogger(AdviceConfig.class);

    @Pointcut("execution(* com.kfm.anno..*.*(..))")
    public void pt(){}

    /**
     * 方法执行前
     */
    @Before("pt()")
    public void before(){
        System.out.println("开始执行。。。");
    }

    /**
     * 方法执行结束
     */
    @After("pt()")
    public void after(){
        System.out.println("结束执行");
    }

    /**
     * 发生异常
     */
    @AfterThrowing("pt()")
    public void exceptionMethod(){
        System.out.println("发生异常了");
    }

    /**
     * 方法返回后执行
     */
    @AfterReturning("pt()")
    public void returnMethod(){
        System.out.println("方法返回了");
    }

    /**
     * 环绕通知
     *  所有的执行都进入这个方法
     */
    @Around("pt()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        Object obj = null;
        String methodName = proceedingJoinPoint.getSignature().getName();
        String className = proceedingJoinPoint.getTarget().getClass().getName();

        String name = className + "." + methodName;

        try {
            Class<?> aClass = Class.forName(className);

            Method method = aClass.getDeclaredMethod(methodName);

            M annotation = method.getAnnotation(M.class);

            System.out.println(annotation.value());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        try {

            LOG.error(name + "方法开始执行" + new Date());
            // 执行方法
            obj = proceedingJoinPoint.proceed();
            System.out.println();
            LOG.info(name + "方法执行成功。返回值是: " + obj);
        } catch (Throwable e) {
            e.printStackTrace();
            LOG.error(name + "在执行时发生了异常");
        }
        return obj;
    }

}
